//
// Created by liaohailong on 2025/4/18.
//

#ifndef HELLOVIDEOCACHE_HELLOPLAYLISTHANDLER_HPP
#define HELLOVIDEOCACHE_HELLOPLAYLISTHANDLER_HPP


#include "HelloRequestHandler.hpp"
#include "../util/HelloHeader.hpp"
#include "../fetcher/HelloDownloader.hpp"
#include "../handler/NativeHandler.hpp"

/**
 * create by liaohailong
 * 2025/4/18 21:26
 * desc: 处理 请求完整 播放列表 式的多媒体文件 eg： m3u8
 *
 * 职责：
 * 1，把播放列表文件，全部下好再放到本地，确保本地如果有数据，就一定是全量的
 * 2，无论是从网络获取到的数据，还是从本地缓存读取到的数据，都需要替换url（源url替换成我们的代理url）
 */
class HelloPlaylistHandler : public HelloRequestHandler
{
public:
    typedef std::string (*UrlTransformer)(const std::string &uri, void *userdata);

    typedef struct
    {
        HelloPlaylistHandler *handler;
        std::shared_ptr<HelloHttpRequest> request;
        std::shared_ptr<HelloCacheInfo> cacheInfo;
        std::shared_ptr<HelloFile> file;
    } HelloPlaylistCtx;

public:
    explicit HelloPlaylistHandler(const std::shared_ptr<HelloCacheManager> &cache);

    ~HelloPlaylistHandler() override;

    void setUrlTransformer(UrlTransformer transformer, void *userdata);

    [[nodiscard]] std::shared_ptr<HelloCacheManager> getCacheManager() const;

    void acceptClient(std::shared_ptr<HelloHttpRequest> request) override;

private:
    std::string parseM3u8(const std::shared_ptr<HelloFile> &file);

    static void write2client(void *userdata);

    static void requestNetwork(void *userdata);

    /**
     * 转换m3u8文件中的内容，把相对资源地址都换成完整的url
     * @param content m3u8整体内容
     * @param prefix 拼接在相对资源地址前面的内容
     * @param file 写入文件
     * @return 转换好的内容
     */
    static std::string transformM3u8Content(const std::string &content,
                                            const std::string& prefix);

private:
    // 缓存大管家
    std::shared_ptr<HelloCacheManager> cache;

    // 单线事件驱动模型
    NHandlerThread *ht;
    NHandler *handler;

    /**
     * m3u8文件中的url，转换器
     */
    UrlTransformer transformer;
    void *userdata;
};


#endif //HELLOVIDEOCACHE_HELLOPLAYLISTHANDLER_HPP
